﻿using System;
using System.IO;
using System.Windows.Forms;
using Microsoft.Win32;
using System.Threading;

namespace Warl
{
    public partial class SmartSense : Form
    {
        private Thread Worker;
        private delegate void addItemDelegate(string item);
        private delegate void performStepDelegate();
        private delegate void addProgressLimitDelegate(int i);
        private delegate void setStatusTextDelegate(string currentDir);
        private delegate void finishedScanDelegate();

        public SmartSense()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Worker = new Thread(new ParameterizedThreadStart(fullSearch));
            Worker.Start();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            Worker = new Thread(new ParameterizedThreadStart(quickSearch));
            Worker.Start();
        }

        private void listView1_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            Settings.wowPath = getSelectedItem().SubItems[0].Text;
            this.Close();
        }

        private ListViewItem getSelectedItem()
        {
            if (listView1.SelectedItems.Count >= 1)
            {
                return listView1.SelectedItems[0];
            }
            else { return null; }
        }

        #region Search Worker

        private void quickSearch(object obj)
        {
            button1.Enabled = false;
            button2.Enabled = false;
            //
            string[] quickResults = smartSenseSearch.quickSearch();
            for (int i = 0; i < (quickResults.Length); i++)
            {
                addItem(quickResults[i]);
            }
        }

        private void fullSearch(object obj)
        {
            button1.Enabled = false;
            button2.Enabled = false;
            //
            quickSearch(null);
            searchFolder("C://");
        }

        private void searchFolder(string path, bool recursive = true)
        {
            try
            {
                string[] folders = Directory.GetDirectories(path);
                addProgressLimit(folders.Length);
                foreach (string folder in folders)
                {
                    setStatusText(folder);
                    if (smartSenseSearch.validWoW(folder)) { addItem(folder); }
                    //
                    performStep();
                    Thread.Sleep(20);
                    //
                    if (recursive) { searchFolder(folder); }
                }
            }
            catch (Exception) { /*MessageBox.Show(e.Message);*/ }
        }

        public void addItem(string _item)
        {
            if (InvokeRequired)
            {
                BeginInvoke(new addItemDelegate(addItem), new object[] { _item });
                return;
            }
            //
            ListViewItem item = new ListViewItem(new string[] { _item, smartSenseSearch.getWoWVersion(_item)  });
            listView1.Items.Add(item);
        }

        private void performStep()
        {
            if (InvokeRequired)
            {
                BeginInvoke(new performStepDelegate(performStep), new object[] { });
                return;
            }
            //
            progressBar1.PerformStep();
            label1.Text = progressBar1.Value + "/" + progressBar1.Maximum;
        }

        private void addProgressLimit(int i)
        {
            if (InvokeRequired)
            {
                BeginInvoke(new addProgressLimitDelegate(addProgressLimit), new object[] { i });
                return;
            }
            //
            progressBar1.Maximum += i;
            label1.Text = progressBar1.Value + "/" + progressBar1.Maximum;
        }

        private void setStatusText(string currentDir)
        {
            if (InvokeRequired)
            {
                BeginInvoke(new setStatusTextDelegate(setStatusText), new object[] { currentDir });
                return;
            }
            //
            label3.Text = currentDir;
        }

        private void finishedScan()
        {
            if (InvokeRequired)
            {
                BeginInvoke(new finishedScanDelegate(finishedScan), new object[] { });
                return;
            }
            //
            button1.Enabled = true;
            button2.Enabled = true;
        }

        #endregion
    }

    #region smartSenseSearch

    public static class smartSenseSearch
    {
        public static string[] quickSearch()
        {
            string[] paths = new String[0];
            string installPath, temp;
            //
            // Read install path
            //
            installPath = new clsRegistry().GetStringValue(Registry.LocalMachine, "SOFTWARE\\Blizzard Entertainment\\World of Warcraft", "InstallPath");
            if (validWoW(installPath)) { paths = addString(paths, installPath); }
            //
            // Check normal install paths
            //
            temp = Environment.GetEnvironmentVariable("PROGRAM_FILES") + "\\Games\\World of Warcraft\\";
            if ((temp != installPath) && (validWoW(temp)))
            {
                paths = addString(paths, temp);
            }
            temp = Environment.GetEnvironmentVariable("PUBLIC") + "\\Games\\World of Warcraft\\";
            if ((temp != installPath) && (validWoW(temp)))
            {
                paths = addString(paths, temp);
            }
            //
            return paths;
        }

        public static string realmlistSearch(string path)
        {
            string[] folders = Directory.GetDirectories(path + "Data");
            foreach (string folder in folders)
            {
                if (File.Exists(folder + "\\realmlist.wtf"))
                {
                    return folder;
                }
            }
            return null;
        }

        public static bool validWoW(string path)
        {
            if ((!String.IsNullOrEmpty(path)) && (File.Exists(path + "Wow.exe"))) { return true; }
            return false;
        }

        public static string getWoWVersion(string path)
        {
            System.Diagnostics.FileVersionInfo myFI = System.Diagnostics.FileVersionInfo.GetVersionInfo(path + "Wow.exe");
            return myFI.FileVersion;
        }

        private static string[] addString(string[] oldList, string value)
        {
            string[] newList = new string[oldList.Length + 1];
            if (oldList.Length > 0)
            {
                for (int i = 0; i < oldList.Length; i++)
                {
                    newList[i] = oldList[i];
                }
            }
            newList[oldList.Length] = value;
            return newList;
        }
    }

    #endregion
}
